home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr10 / tvprompt.zip / READER.PKG < prev    next >
Text File  |  1992-05-29  |  4KB  |  121 lines

  1. with Command_Line,
  2.      DOS_IO,
  3.      Screen;
  4.  
  5. -- Copyright 1991,92 Tom Moran
  6.  
  7. package body Reader is
  8.  
  9.   task body Read_File is
  10.     Patience: Duration := 0.0;
  11.     subtype Printable_Chars is Character range ' ' .. '~';
  12.     subtype Visible_Chars is Character range '!' .. '~';
  13.     Char    : Character;
  14.     The_Line: Screen.Scrollable_Strings;
  15.     F       : DOS_IO.File_Handle;
  16.     Ctrl_Z  : constant Character := Ascii.Sub;
  17.     Max_Back_Off: constant := 10; -- max back up looking for word break
  18.     subtype Buffer_Indices is Integer range 1 .. 256 + Max_Back_Off;
  19.     Buffer  : String(Buffer_Indices);
  20.     Read_Count: Natural;
  21.     Current_Char_Index: Integer
  22.       range Buffer_Indices'First .. Buffer_Indices'Last + 1
  23.         := Buffer_Indices'Last + 1;
  24.     Last_Char_Index: Integer
  25.       range Buffer_Indices'First - 1 .. Buffer_Indices'Last
  26.         := Buffer_Indices'First - 1;
  27.  
  28.   begin
  29.  
  30.     accept Start_Up;
  31.     if Command_Line.Parameter_Count = 1 then
  32.       DOS_IO.Open(Command_Line.Parameter(1), F);
  33.     end if;
  34.  
  35.     Reading_Lines:
  36.     loop
  37.       The_Line := "                    ";
  38.       exit Reading_Lines when not DOS_IO.Is_Open(F);
  39.  
  40.       Reading_Characters:
  41.       for I in The_Line'range loop
  42.         if Current_Char_Index > Last_Char_Index then
  43.           Current_Char_Index := Buffer'First + Max_Back_Off;
  44.           Read_Count := Integer(DOS_IO.Read(F, Buffer(Current_Char_Index)'
  45.             Address, DOS_IO.Byte_Counts(Buffer'Length - Max_Back_Off)));
  46.           if Read_Count = 0 then
  47.             DOS_IO.Close(F);
  48.             exit Reading_Characters;
  49.           end if;
  50.           Last_Char_Index := Current_Char_Index + Read_Count - 1;
  51.         end if;
  52.         Char := Buffer(Current_Char_Index);
  53.         Current_Char_Index := Current_Char_Index + 1;
  54.         if Char = Ctrl_Z then
  55.           DOS_IO.Close(F);
  56.           exit Reading_Characters;
  57.         end if;
  58.         if Char in Printable_Chars then
  59.           The_Line(I) := Char;
  60.           exit Reading_Characters when Char = '.';
  61.         else
  62.           The_Line(I) := ' ';
  63.         end if;
  64.       end loop Reading_Characters;
  65.  
  66.       -- if The_Line ends with a partial word, scan back a ways for a
  67.       -- blank and break it there instead.
  68.       if The_Line(The_Line'Last) /= ' '
  69.           and (Current_Char_Index <= Last_Char_Index
  70.             and then Buffer(Current_Char_Index) in Visible_Chars) then
  71.  
  72.         Scan_Back_For_Blank:
  73.         for I in reverse The_Line'Last-Max_Back_Off .. The_Line'Last-1 loop
  74.           if The_Line(I) = ' ' then
  75.             Buffer(Current_Char_Index - (The_Line'Last - I)
  76.                    .. Current_Char_Index - 1)
  77.               := The_Line(I + 1 .. The_Line'Last);
  78.             The_Line(I + 1 .. The_Line'Last):=(I+1 .. The_Line'Last => ' ');
  79.             Current_Char_Index := Current_Char_Index - (The_Line'Last - I);
  80.             exit Scan_Back_For_Blank;
  81.           end if;
  82.         end loop Scan_Back_For_Blank;
  83.  
  84.       end if;
  85.       -- The_Line is ready to display.
  86.  
  87.       -- allow termination or defer requests.
  88.       -- if none, put The_Line on the screen
  89.       select
  90.         accept Premature_Death;
  91.       or
  92.         accept Defer(How_Long: in     Duration) do
  93.           Patience := How_Long;
  94.         end;
  95.         -- request to defer a while to keyboard.
  96.         -- continue defering until End_Defer or timeout
  97.         Deferring:
  98.         loop
  99.           select
  100.             accept Continue_Deferring;  -- just restart Patience delay
  101.           or
  102.             accept End_Defer;           -- immediately quit deferring
  103.             exit;
  104.           or
  105.             delay Patience;                -- or wait for Patience timeout
  106.             exit;
  107.           end select;
  108.         end loop Deferring;
  109.       else
  110.         Screen.Scroller.Put(The_Line);
  111.       end select;
  112.     end loop Reading_Lines;
  113.     -- all done reading lines.  Let this task die.
  114.  
  115.   exception
  116.     when DOS_IO.Name_Error =>  -- no such file.  Let this task die.
  117.       null;
  118.   end Read_File;
  119.  
  120. end Reader;
  121.